#pragma once
#include <map>
#include <string>
#include <fstream>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <queue>

namespace U32
{
	using namespace std;
	struct data_v
	{
		string ip;
		int connections;
		data_v(string ip, int connections)
		{
			this->ip = ip;
			this->connections = connections;
		}

		friend bool operator<(const data_v &lop, const data_v &rop) { return lop.connections < rop.connections; }
	};
	struct data_pq
	{
		string ip;
		int connections;
		data_pq(string ip, int connections)
		{
			this->ip = ip;
			this->connections = connections;
		}

		friend bool operator<(const data_pq &lop, const data_pq &rop) { return lop.connections < rop.connections; }
	};

	class map_ip : map<string, data_v>
	{
	public:
		void read_from_file(string filename)
		{
			string row, str;
			try
			{
				ifstream fin(filename);
				while (getline(fin, row))
				{
					istringstream iss(row);
					getline(iss, str, ' ');
					if (str.length() > 0)
					{
						auto it = this->find(str);
						if (it == this->end())
							this->emplace(str, data_v(str, 1));
						else
							it->second.connections++;
					}
				}
				fin.close();
			}
			catch (exception e)
			{
				cout << e.what() << endl;
			}
		}

		int num_connections(string ip)
		{
			auto it = this->find(ip);
			if (it != this->end())
				return it->second.connections;
			else
				return -1;
		}

		void print_max_connected()
		{
			priority_queue<data_pq> queue;
			for (auto &p : *this)
			{
				data_pq d(p.second.ip, p.second.connections);
				queue.push(d);
			}
			for (int i = 0; i < 10; i++)
			{
				cout << queue.top().ip << ":" << queue.top().connections << endl;
				queue.pop();
			}
		}

	};
}

